package com.xiaolong.nacos.config;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.loadbalancer.NacosLoadBalancer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.Request;
import org.springframework.cloud.client.loadbalancer.Response;
import org.springframework.cloud.loadbalancer.core.ReactorServiceInstanceLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import reactor.core.publisher.Mono;


@AutoConfiguration
public class NacosLoadBalancerConfig {

    private static final Logger logger = LoggerFactory.getLogger(NacosLoadBalancerConfig.class);

    @Bean
    @ConditionalOnMissingBean
    public ReactorServiceInstanceLoadBalancer reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory, NacosDiscoveryProperties nacosDiscoveryProperties) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        logger.info("Configuring NacosLoadBalancer for service: {}", name);

        return new NacosLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name, nacosDiscoveryProperties) {
            @Override
            public Mono<Response<ServiceInstance>> choose(Request request) {
                logger.debug("LoadBalancer received request: {}", request);
                return super.choose(request).doOnNext(response -> {
                    if (response.hasServer()) {
                        logger.info("Selected instance: {} for service: {}", response.getServer().getUri(), name);
                    } else {
                        logger.warn("No available instances found for service: {}", name);
                    }
                });
            }
        };
    }


}
